package com.myfoon.model.entity;

import com.tangosol.io.ExternalizableLite;

import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
import com.tangosol.util.ExternalizableHelper;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;

import java.sql.Timestamp;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.QueryHint;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@NamedQueries( 
                { 
                @NamedQuery(name = "User.findByEmailAndPassword",
                             query = "select u from User u left join fetch u.userPi where u.email = :email and u.passwd = :passwd",
                             hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true"),
                                      @QueryHint(name = "org.hibernate.cacheRegion", value = "UserRegion")
                                      }
                             )                            
                ,
                @NamedQuery(name = "User.findUserDetails", 
                            query = "select pi from UserPi pi where pi.id = :pi_id",
                            hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true"),
                                     @QueryHint(name = "org.hibernate.cacheRegion", value = "UserRegion")
                                     }
                            )
                ,
               @NamedQuery(name = "User.findFriendIDs",
                           query = "select fr.friend.id from Friend fr where fr.owner.id = :owner_id"                           
                           )
                ,
               @NamedQuery(name = "User.findFriendINPs",
                           query = "select fr.friend.id, fr.friend.userPi.fullname, fr.friend.photoSmall from Friend fr left join fr.friend.userPi where fr.owner.id = :owner_id",
                           hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true"),
                                    @QueryHint(name = "org.hibernate.cacheRegion", value = "UserRegion")
                                    }
                           )
                ,                
               @NamedQuery(name = "User.areFriends",
                           query = "select count(*) from Friend fr where " +
                                   "(fr.owner.id = :user1_id and fr.friend.id = :user2_id) or " +
                                   "(fr.owner.id = :user2_id and fr.friend.id = :user1_id)",                           
                           hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true")}
                          )
               }
            )
@Entity
@Table(name = "USER")
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class User implements Serializable {
    private Long id;
    private UserPi userPi;

    private String email;
    private String passwd;

    private String photoNormal;
    private String photoSmall;

    private short status;
    private Timestamp created;

    public User() {
        userPi = new UserPi();
        this.setStatus((short)1);
    }

    public User(UserPi userPi, String email, String passwd) {
        this();
        this.userPi = userPi;
        this.email = email;
        this.passwd = passwd;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Id
    @GeneratedValue(generator = "UserSequence", strategy = GenerationType.AUTO)
    @SequenceGenerator(name = "UserSequence", allocationSize = 1,
                       sequenceName = "USER_SEQ_01")
    @Column(name = "ID", unique = true, nullable = false)
    public Long getId() {
        return id;
    }

    public void setUserPi(UserPi userPi) {
        this.userPi = userPi;
    }

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "USER_PI_ID")
    public UserPi getUserPi() {
        return userPi;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Column(name = "EMAIL", length = 60, nullable = false, unique = true)
    public String getEmail() {
        return email;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    @Column(name = "PASSWD", length = 15, nullable = false)
    public String getPasswd() {
        return passwd;
    }

    public void setStatus(short status) {
        this.status = status;
    }

    @Column(name = "STATUS", nullable = false)
    public short getStatus() {
        return status;
    }

    public void setCreated(Timestamp created) {
        this.created = created;
    }

    @Column(name = "CREATED")
    public Timestamp getCreated() {
        return created;
    }

    public void setPhotoNormal(String photoNormal) {
        this.photoNormal = photoNormal;
    }

    @Column(name = "PHOTO_NORMAL")
    public String getPhotoNormal() {
        return photoNormal;
    }

    public void setPhotoSmall(String photoSmall) {
        this.photoSmall = photoSmall;
    }

    @Column(name = "PHOTO_SMALL")
    public String getPhotoSmall() {
        return photoSmall;
    }
}
